"""
Data tracking implementations
"""

"""
    DataTracker

Tracks scalar quantities extracted from fields over time.
"""
mutable struct DataTracker
    quantities::Vector{String}
    times::Vector{Float64}
    data::Dict{Symbol, Vector{Float64}}
    
    function DataTracker(quantities::Vector{String})
        data_dict = Dict{Symbol, Vector{Float64}}()
        for q in quantities
            data_dict[Symbol(q)] = Float64[]
        end
        new(quantities, Float64[], data_dict)
    end
end

function track!(tracker::DataTracker, field, time::Float64)
    push!(tracker.times, time)
    
    for q in tracker.quantities
        value = if q == "norm"
            norm(field)
        elseif q == "max_value"  
            maximum(abs.(data(field)))
        elseif q == "integral"
            integrate(field)
        elseif q == "min_value"
            minimum(data(field))
        elseif q == "mean_value"
            sum(data(field)) / length(data(field))
        else
            0.0  # Default value
        end
        
        push!(tracker.data[Symbol(q)], value)
    end
end

function get_tracker_data(tracker::DataTracker)
    result = (times = copy(tracker.times),)
    for (key, values) in tracker.data
        result = merge(result, NamedTuple{(key,)}((copy(values),)))
    end
    return result
end

"""
    SteadyStateTracker

Detects when simulation reaches steady state.
"""
mutable struct SteadyStateTracker
    rtol::Float64
    window_size::Int
    values::Vector{Float64}
    converged::Bool
    
    function SteadyStateTracker(; rtol=1e-3, window_size=10)
        new(rtol, window_size, Float64[], false)
    end
end

function track!(tracker::SteadyStateTracker, field, time::Float64)
    # Use norm as convergence metric
    current_value = norm(field)
    push!(tracker.values, current_value)
    
    # Keep only window_size most recent values
    if length(tracker.values) > tracker.window_size
        popfirst!(tracker.values)
    end
    
    # Check convergence if we have enough values
    if length(tracker.values) >= tracker.window_size
        relative_change = (maximum(tracker.values) - minimum(tracker.values)) / mean(tracker.values)
        tracker.converged = relative_change < tracker.rtol
    end
end

# Aliases for compatibility
const PlotTracker = DataTracker
const CallbackTracker = DataTracker